home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 401-425 / disk_405 / gifmachine / sources / 24to12.c next >
C/C++ Source or Header  |  1992-05-06  |  4KB  |  168 lines

  1. /* Copyright 1990 by Christopher A. Wichura.
  2.    See file GIFMachine.doc for full description of rights.
  3. */
  4.  
  5. #include "GIFMachine.h"
  6.  
  7. extern struct GIFdescriptor gdesc;
  8. EXTERNBITPLANE;
  9.  
  10. /* since both MasterColourTable and the PaletteBuf are the same size and
  11.    type we will define MCT to be the PaletteBuf to cut down on static
  12.    memory declarations */
  13. #define MasterColourTable PaletteBuf
  14.  
  15. extern UBYTE MasterColourTable[MAXCOLOURS];
  16. static UWORD TotalColours;
  17.  
  18. extern BYTE *CurrentLineErr[3];
  19. extern BYTE *LastLineErr[3];
  20.  
  21. extern char *AbortMsg;
  22.  
  23. #define MAXERR 2
  24.  
  25. void ReduceTo12(void)
  26. {
  27.     register UWORD x;
  28.     register UWORD y;
  29.  
  30.     PutStr("...Reducing palette to 12 bits.\n......Line ");
  31.  
  32.     TotalColours = 0;
  33.     memset((char *)MasterColourTable, 0, sizeof(MasterColourTable));
  34.  
  35.     for (y = 0; y < gdesc.gd_Height; y++) {
  36.         MyPrintf("%5ld", y);
  37.  
  38.         if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
  39.             MyPrintf("\n%s", AbortMsg);
  40.             MyExit(ABORTEXITVAL);
  41.         }
  42.  
  43.         for (x = 0; x < gdesc.gd_Width; x++)
  44.             PutValue(x, y, AddColour(&BitPlane[y][x]));
  45.  
  46.         PutStr("\x9B" "5D");
  47.     }
  48.  
  49.     MyPrintf("\x9B" "5D%ld total unique colours used.\n", TotalColours);
  50. }
  51.  
  52. void DitherTo12(void)
  53. {
  54.     register UWORD x;
  55.     register UWORD y;
  56.     register int RedErr;
  57.     register int GreenErr;
  58.     register int BlueErr;
  59.     BYTE **cerr, **lerr, **terr;
  60.     struct RGB rgb;
  61.  
  62.     PutStr("...Dithering palette to 12 bits.\n......Setup");
  63.  
  64.     TotalColours = 0;
  65.     memset((char *)MasterColourTable, 0, sizeof(MasterColourTable));
  66.  
  67.     cerr = (BYTE **)&CurrentLineErr[0];
  68.     lerr = (BYTE **)&LastLineErr[0];
  69.  
  70.     /* the top, left and right borders will be used unmodified */
  71.  
  72.     for (x = 0; x < gdesc.gd_Width; x++)
  73.         PutValue(x, 0, AddColour(&BitPlane[0][x]));
  74.  
  75.     for (y = 1; y < gdesc.gd_Height; y++) {
  76.         PutValue(0, y, AddColour(&BitPlane[y][0]));
  77.         PutValue(gdesc.gd_Width - 1, y, AddColour(&BitPlane[y][gdesc.gd_Width - 1]));
  78.     }
  79.  
  80.     /* since the error tables are alloced with MEMF_CLEAR we won't bother
  81.        to clear them here.  instead, we just hit the main loop */
  82.  
  83.     PutStr("\x9B" "5DLine ");
  84.  
  85.     for (y = 1; y < gdesc.gd_Height; y++) {
  86.         MyPrintf("%5ld", y);
  87.  
  88.         if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
  89.             MyPrintf("\n%s", AbortMsg);
  90.             MyExit(ABORTEXITVAL);
  91.         }
  92.  
  93.         for (x = 1; x < (gdesc.gd_Width - 1); x++) {
  94.             rgb = BitPlane[y][x];
  95.  
  96.             RedErr   = cerr[0][x - 1] + 7*lerr[0][x - 1] + 5*lerr[0][x] + 3*lerr[0][x + 1];
  97.             GreenErr = cerr[1][x - 1] + 7*lerr[1][x - 1] + 5*lerr[1][x] + 3*lerr[1][x + 1];
  98.             BlueErr  = cerr[2][x - 1] + 7*lerr[2][x - 1] + 5*lerr[2][x] + 3*lerr[2][x + 1];
  99.  
  100.             RedErr   >>= 4;
  101.             GreenErr >>= 4;
  102.             BlueErr  >>= 4;
  103.  
  104.     /* now we add the errors into the colour we want.  if this would push
  105.        us over 255 (and thus out of range) we subtract the error out so
  106.        that we still see some dithering instead of washing out the area. */
  107.  
  108.             if (rgb.rgb_Red + RedErr > 255)
  109.                 rgb.rgb_Red -= RedErr;
  110.             else
  111.                 rgb.rgb_Red += RedErr;
  112.  
  113.             if (rgb.rgb_Green + GreenErr > 255)
  114.                 rgb.rgb_Green -= GreenErr;
  115.             else
  116.                 rgb.rgb_Green += GreenErr;
  117.  
  118.             if (rgb.rgb_Blue + BlueErr > 255)
  119.                 rgb.rgb_Blue -= BlueErr;
  120.             else
  121.                 rgb.rgb_Blue += BlueErr;
  122.  
  123.             PutValue(x, y, AddColour(&rgb));
  124.  
  125.             RedErr   = (int)rgb.rgb_Red   - (int)(rgb.rgb_Red   & 0xF0);
  126.             GreenErr = (int)rgb.rgb_Green - (int)(rgb.rgb_Green & 0xF0);
  127.             BlueErr  = (int)rgb.rgb_Blue  - (int)(rgb.rgb_Blue  & 0xF0);
  128.  
  129.             if (RedErr > MAXERR)
  130.                 RedErr = (RedErr * 3) >> 2;
  131.  
  132.             if (GreenErr > MAXERR)
  133.                 GreenErr = (GreenErr * 3) >> 2;
  134.  
  135.             if (BlueErr > MAXERR)
  136.                 BlueErr = (BlueErr * 3) >> 2;
  137.  
  138.             cerr[0][x] = RedErr;
  139.             cerr[1][x] = GreenErr;
  140.             cerr[2][x] = BlueErr;
  141.         }
  142.  
  143.             terr = lerr;
  144.             lerr = cerr;
  145.             cerr = terr;
  146.  
  147.         PutStr("\x9B" "5D");
  148.     }
  149.  
  150.     MyPrintf("\x9B" "5D%ld total unique colours used.\n", TotalColours);
  151. }
  152.  
  153. UWORD AddColour(struct RGB *rgb)
  154. {
  155.     register UWORD colour;
  156.  
  157.     colour = ((rgb->rgb_Red << 4) & 0xF00) |
  158.          (rgb->rgb_Green & 0xF0) |
  159.          (rgb->rgb_Blue >> 4);
  160.  
  161.     if (!MasterColourTable[colour]) {
  162.         MasterColourTable[colour] = 1;
  163.         TotalColours++;
  164.     }
  165.  
  166.     return colour;
  167. }
  168.